﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;


namespace Raytracererer
{
    class TexturedPlane : Plane
    {
        Bitmap texture;
        byte[] textureData;
        int textureWidth, textureHeight;
        Vector3 localRight;
        Vector3 localUp;
        public double scale = 0.5; //~bilder per 1*1-enhet
        public TexturedPlane(Vector3 point, Vector3 normal, Color color, Bitmap texture)
            : base(point, normal, color)
        {
            this.texture = texture;
            textureWidth = texture.Width;
            textureHeight = texture.Height;
            BitmapData data = texture.LockBits(new Rectangle(0, 0, texture.Width, texture.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            IntPtr tex = data.Scan0;
            textureData = new byte[4 * data.Stride * textureHeight];
            System.Runtime.InteropServices.Marshal.Copy(tex, textureData, 0, data.Stride * textureHeight);


            //introducerar två lokala koordinataxlar
            //just nu är de projektioner av upp y resp z på planet
            localUp = new Vector3(0, 1, 0) - (new Vector3(0, 1, 0) * normal) * normal;
            localUp = localUp.Normalized();
            localRight = new Vector3(0, 0, 1) - (new Vector3(0, 0, 1) * normal) * normal;
            localRight = localRight.Normalized();

        }
        public override Color ColorAt(Vector3 position)
        {
            Vector3 relativePosition = position - point;
            //fuskar med absolutbelopp eftersom modulus % i C# tydligen inte ger positiva resten
            //en custom % som ger det matematiskt förväntade skulle uppskattas
            double x = relativePosition * localRight * textureWidth * scale;
            double y = relativePosition * localUp * textureHeight * scale;
            //System.Drawing.Color c = texture.GetPixel((int)(x % texture.Width+(x<0?texture.Width:0)),
            //    (int)(y % texture.Height + (y < 0 ? texture.Height: 0)));
            //return new Color(c.R / 255.0, c.G / 255.0, c.B / 255.0) *color;
            double r, g, b;
            int x2 = (int)(x % textureWidth + (x < 0 ? textureWidth : 0));
            int y2 = (int)(y % textureHeight + (y < 0 ? textureHeight : 0));
            r = textureData[(x2 + textureWidth * y2) * 4] / 255.0;
            g = textureData[(x2 + textureWidth * y2) * 4 + 1] / 255.0;
            b = textureData[(x2 + textureWidth * y2) * 4 + 2] / 255.0;

            return new Color(r, g, b);
        }
    }
}
